#include "Precompile.h"
#include "DX11VertexInputLayout.h"
#include "DX11RenderSystem.h"

namespace Graphics{
	DX11VertexInputLayout::DX11VertexInputLayout():m_inputLayout(NULL){
	}

	DX11VertexInputLayout::~DX11VertexInputLayout(){
		if(m_inputLayout)
			m_inputLayout->Release();
	}

	void DX11VertexInputLayout::buildLayout(RenderContext* context, void* byteCodeRef, size_t byteCodeSize){
		if(m_sematics.empty() || !byteCodeRef || byteCodeSize == 0){
			LOG_ERROR("Unable to build layout, missing needed information.");
			assert(0);
			return;
		}

		DX11RenderContext* ctx = (DX11RenderContext*)context;

		D3D11_INPUT_ELEMENT_DESC* vertLayout = new D3D11_INPUT_ELEMENT_DESC[m_sematics.size()];
		for(unsigned int i=0; i<m_sematics.size(); i++){
			vertLayout[i].SemanticName = m_sematics[i].c_str();
			vertLayout[i].SemanticIndex = 0;
			vertLayout[i].InputSlot = 0;
			vertLayout[i].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
			vertLayout[i].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
			vertLayout[i].InstanceDataStepRate = 0;

			switch(m_strides[i]){
			case 2:
				vertLayout[i].Format = DXGI_FORMAT_R32G32_FLOAT;
				break;
			case 3:
				vertLayout[i].Format = DXGI_FORMAT_R32G32B32_FLOAT;
				break;
			case 4:
				vertLayout[i].Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
				break;
			default:
				LOG_ERROR("Unimplemented stride value set.");
				assert(0);
				return;
			}
		}

		HRESULT hr = ctx->m_handle->CreateInputLayout(vertLayout,m_sematics.size(),byteCodeRef,byteCodeSize,&m_inputLayout);
		if(FAILED(hr)){
			LOG_ERROR("Failed in creating inputlayout.");
			assert(0);
			return;
		}
	}

	void DX11VertexInputLayout::setLayout(RenderContext* context){
		DX11RenderContext* ctx = (DX11RenderContext*)context;

		ctx->m_context->IASetInputLayout(m_inputLayout);
	}
}